﻿using s3pi.Interfaces;
using s3pi.Package;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PackageViewer
{

    public class ViewItem : ListViewItem//, IComparer
    {
        private Kuree.Sims3.ViewItem item;
        public bool SortByName { get; set; }
        public bool IsCorupted { get; set; }
        public ViewItem(string name = "Unknown", string path = "", Kuree.Sims3.ViewItem.TypeFlag type = Kuree.Sims3.ViewItem.TypeFlag.Object, bool sortbyName = true) : base(name)
        {
            IPackage pack;
            item = new Kuree.Sims3.ViewItem(name, path, type, null);
            try
            {
                pack = Package.OpenPackage(0, path);
                item.IsCorrupted = false;
                this.IsCorupted = false;
            }
            catch
            {
                item.IsCorrupted = true;
                this.IsCorupted = true;
                this.ImageKey = "Bad";
                //MessageBox.Show(ex.ToString());
            }
            finally
            {
                pack = null;
            }

            //item = new Kuree.Sims3.ViewItem(name, path, type, null);
            if (item.Enabled && (!item.IsCorrupted))
            {
                this.ImageKey = "Enabled";
            }
            else if(!(item.Enabled) && (!item.IsCorrupted))
            {
                this.ImageKey = "Disabled";
            }
            this.SortByName = sortbyName;
            
        }

        // Wrap the item implement and interface

        public string Path { get { return item.Path; } }
        public string RootFolder { get; set; }

        public bool Enabled 
        { 
            get 
            { 
                return item.Enabled;
            } 
            set 
            { 
                item.Enabled = value;
                if (!IsCorupted)
                {
                    switch (value)
                    {
                        case true:
                            this.ImageKey = "Enabled";
                            break;
                        case false:
                            this.ImageKey = "Disabled";
                            break;
                    }
                }
                else
                {
                    this.ImageKey = "Bad";
                }
            }
        }
        public ulong Instance { get { return item.Instance; } set { item.Instance = value; } }
        public Kuree.Sims3.ViewItem.TypeFlag Flag { get { return item.Flag; } set { item.Flag = value; } }
        public Stream ImageStream { get { return item.ImageStream; } set { item.ImageStream = value; } }
        private DateTime Time
        {
            get
            {
                System.IO.FileInfo info = new FileInfo(Path);
                return info.LastWriteTime;
            }
        }
        //public string Name { get { return item.Name; } set { item.Name = value; } }

        public override string ToString()
        {
            return item.ToString();
            
        }

        new public string Text
        {
            get
            {
                return item.ToString();
            }
        }

        public class CompareItem :IComparer
        {
            private bool SortByName;
            public CompareItem(bool sort = true) { this.SortByName = sort; }
            public int Compare(object obj1, object obj2)
            {
                if (SortByName)
                {
                    if (obj2 == null)
                        return 1;
                    if (obj1 == null)
                        return -1;
                    ViewItem item1 = obj1 as ViewItem;
                    ViewItem item2 = obj2 as ViewItem;
                    return item1.item.Name.CompareTo(item2.item.Name);
                }
                else
                {
                    if (obj2 == null)
                        return 1;
                    if (obj1 == null)
                        return -1;
                    ViewItem item1 = obj1 as ViewItem;
                    ViewItem item2 = obj2 as ViewItem;

                    return item1.Time.CompareTo(item2.Time);
                }
            }

        }

        
        
    }


    public class CASP : Item
    {
        
        public CASPartResource.CASPartResource CAS { get; set; }
        public override string PropertyText { get { return CAS.Clothing.ToString(); } }

        public override string ToString()
        {
            return "[CAS] " + Name;
        }

        public CASP(string name, string path, List<Image> list, CASPartResource.CASPartResource cas)
            : base(name, path, list)
        {
            
            this.CAS = cas;
        }
    }

    public class OBJD :Item 
    {
        
        public CatalogResource.ObjectCatalogResource OBJ { get; set; }
        public override string PropertyText { get { return "Normal Object"; } }

        public override string ToString()
        {
            return "[OBJ] " + Name;
        }

        public OBJD(string name, string path, List<Image> list, CatalogResource.ObjectCatalogResource obj)
            : base(name, path, list)
        {
            
            this.OBJ = obj;
        }

        
    }

    public class CFEN : Item 
    {
        
        public CatalogResource.FenceCatalogResource Cfen { get; set; }
        public override string PropertyText { get { return "Fence Object"; } }

        public override string ToString()
        {
            return "[FEN] " + Name;
        }

        public CFEN(string name, string path, List<Image> list, CatalogResource.FenceCatalogResource cfen)
            : base(name, path, list)
        {
            
            this.Cfen = cfen;
        }
    }

    public class CWAL : Item 
    {
        
        public CatalogResource.WallFloorPatternCatalogResource Cwal { get; set; }
        public override string PropertyText { get { return "Wall Object"; } }

        public override string ToString()
        {
            return "[WAL] " + Name;
        }

        public CWAL(string name, string path, List<Image> list, CatalogResource.WallFloorPatternCatalogResource cwal)
            : base(name, path, list)
        {
            
            this.Cwal = cwal;
        }
    }

    public class CSTR : Item 
    {
        
        public CatalogResource.StairsCatalogResource Cstr { get; set; }
        public override string PropertyText { get { return "Stair Object"; } }

        public override string ToString()
        {
            return "[STR] " + Name;
        }

        public CSTR(string name, string path, List<Image> list, CatalogResource.StairsCatalogResource cstr):base(name, path, list)
        {
            
            this.Cstr = cstr;
        }
    }

    public class CRAL : Item 
    {
        
        public CatalogResource.RailingCatalogResource Cral { get; set; }
        public override string PropertyText { get { return "Stair Railing Object"; } }

        public override string ToString()
        {
            return "[RAL] " + Name;
        }

        public CRAL(string name, string path, List<Image> list, CatalogResource.RailingCatalogResource cral)
            : base(name, path, list)
        {
            //this.Name = name;
            //this.Path = path;
            //this.ImageList = list;
            this.Cral = cral;
        }
    }

    public class CTPT : Item
    {
        
        public CatalogResource.TerrainPaintBrushCatalogResource Ctpt { get; set; }
        public override string PropertyText { get { return "Terrain Painting Object"; } }

        public override string ToString()
        {
            return "[TPT] " + Name;
        }

        public CTPT(string name, string path, List<Image> list, CatalogResource.TerrainPaintBrushCatalogResource ctpt):base(name, path, list)
        {
            
            this.Ctpt = ctpt;
        }
    }

    public class CRMT : Item
    {

        public CatalogResource.RoofPatternCatalogResource Crmt { get; set; }
        public override string PropertyText { get { return "Roof Patterns Object"; } }

        public override string ToString()
        {
            return "[RMT] " + Name;
        }

        public CRMT(string name, string path, List<Image> list, CatalogResource.RoofPatternCatalogResource crmt)
            : base(name, path, list)
        {

            this.Crmt = crmt;
        }
    }


    public class Item
    {
        public string Name { get; set; }
        public string Path { get; set; }
        public List<Image> ImageList { get; set; }
        public int Index { get; set; }
        public virtual string PropertyText { get { return "Unknown"; } }

        public Item(string name, string path, List<Image> list)
        {
            if (name == null || name == "") name = "Unknown";
            this.Name = name;
            this.Path = path;
            this.ImageList = list;
        }
    }


    public class ListConfig : IEnumerable
    {
        private List<string> List;
        public ListConfig(List<string> list)
        {
            this.List = list;
        }
        public ListConfig(Stream s)
        {
            s.Position = 0;
            this.List = Parse(s);
        }

        public Stream UnParse()
        {
            if (List == null || List.Count == 0)
            {
                return null;
            }

            MemoryStream s = new MemoryStream();
            BinaryWriter w = new BinaryWriter(s);
            w.Write(List.Count);

            foreach (string item in List)
            {
                StringWriter(s, item);
            }
            s.Position = 0;

            return s;

        }

        private List<string> Parse(Stream s)
        {
            BinaryReader r = new BinaryReader(s);
            int count = r.ReadInt32();
            List<string> l = new List<string>();
            for (int i = 0; i < count; i++)
            {
                l.Add(StringReader(s));
            }
            return l;
        }

        public IEnumerator GetEnumerator()
        {
            return IEnumerator();
        }

        public IEnumerator<string> IEnumerator()
        {
            foreach (string str in this.List)
            {
                yield return str;
            }
        }

        

        private static void StringWriter(Stream s, string item)
        {
            BinaryWriter w = new BinaryWriter(s);
            byte[] buffer = Encoding.UTF8.GetBytes(item.ToCharArray());
            
            w.Write(buffer.Count());
            w.Write(buffer);
            w.Flush();
        }
        private string StringReader(Stream s)
        {
            BinaryReader r = new BinaryReader(s);
            int count = r.ReadInt32();
            byte[] buffer = r.ReadBytes(count);


            return Encoding.UTF8.GetString(buffer);
        }

        
    }


}
